﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace LinQBases
{
    class Program
    {
        static void Main(string[] args)
        {


            List<Student> studentList = new List<Student>();
            studentList.Add(new Student("Milen", "Stanoev", 71038, "0886192775", "mbs_eagle@abv.bg", new List<int>() { 5, 6, 6 }, 2));
            studentList.Add(new Student("Ivan", "Petrov", 24534, "026243456", "ivan.ivanov@abv.bg", new List<int>() { 5, 4, 6 }, 2));
            studentList.Add(new Student("Andrei", "Andreev", 412306, "02623456", "a.ivanov@abv.bg", new List<int>() { 5, 4, 6 }, 1));
            studentList.Add(new Student("Pesho", "Penev", 41063, "086243566", "ivgfdn.ivanov@gmail.com", new List<int>() { 5, 5, 5 }, 1));
            studentList.Add(new Student("Todor", "Simov", 41243, "08623243456", "idgfn.ivanov@abv.bg", new List<int>() { 3, 4, 6 }, 1));

            var group2 =
                from s in studentList
                where s.GroupNumber == 2
                select s;

            //foreach (var student in group2)
            //{
            //    Console.WriteLine(student.Firstname);
            //}

            Console.WriteLine();
            var group2Extension =
             studentList.Where(s => s.GroupNumber == 2);
            //foreach (var student in group2Extension)
            //{
            //    Console.WriteLine(student.Firstname);
            //}


            //Extract all students that have email in abv.bg. Use string methods and LINQ.

            var abv =
                   from s in studentList
                   where s.Email.EndsWith("@abv.bg")
                   select s;

            var abvExpression =
               studentList.Where(s => s.Email.EndsWith("@abv.bg"));


            //foreach (var student in abvExpression)
            //{
            //    Console.WriteLine(student.Firstname);
            //}


            //Extract all students with phones in Sofia. Use LINQ and regular expressions.

            var inSofia =
       from s in studentList
       where Regex.IsMatch(s.Tel, "02[0-9]{7}")
       select s;

            var inSofiaExpression =
               studentList.Where(s => Regex.IsMatch(s.Tel, "02[0-9]{7}"));


            //foreach (var student in inSofiaExpression)
            //{
            //    Console.WriteLine(student.Firstname);
            //}



            //Select all students that have at least one mark Excellent (6) into a new anonymous class that has properties – FullName and Marks. Use LINQ.

            var excellent =
            from s in studentList
            where s.Marks.Contains(6)
            select new { FullName = s.Firstname + s.LastName, Mark = s.Marks };
            //foreach (var student in excellent)
            //{
            //    Console.WriteLine(student.FullName);
            //}



            //Write down a similar program that extracts the students with exactly  two marks "6". Use extension methods.

            var excellent2 =
    studentList.Where(s => s.Marks.Count(w => w == 6) == 2).Select(s =>
   new { FullName = s.Firstname + s.LastName, Mark = s.Marks });
            //        foreach (var student in excellent2)
            //{
            //    Console.WriteLine(student.FullName);
            //}


            //Extract all Marks of the students that enrolled in 2006. (The students from 2006 have 06 as their 5-th and 6-th digit in the FN).

            var enrolled2006 =
                studentList.Where(s => Regex.IsMatch(s.Fn.ToString(), "[0-9]{4}06[0-9]*")).Select(s => s);
            //foreach (var st in enrolled2006)
            //{
            //    Console.WriteLine(st.LastName+" "+st.AllMarks);
            //}

            //Create a class Group with properties GroupNumber and DepartmentName. Introduce a property Group in the Student class. Extract all students from "Mathematics" department. Use the Join operator.


            List<Group> groupList = new List<Group>();
            groupList.Add(new Group(1, "Mathematika"));
            var Group1Students =
from s in studentList
join
    g in groupList on s.GroupNumber equals g.GroupNumber
select s;
            //foreach (var st in Group1Students)
            //{
            //    Console.WriteLine(st.Firstname);
            //}


            //Write a program to return the string with maximum length from an array of strings. Use LINQ.

            string[] strings = { "agsgag", "asf", "as" };
            var MaxLenght =
                (from s in strings
                 orderby s.Length descending
                 select s).First();

            // Console.WriteLine(MaxLenght);

            //Create a program that extracts all students grouped by GroupName and then prints them to the console. Use LINQ.

            List<Group> groupList1 = new List<Group>();
            groupList1.Add(new Group(1, "Mathematika"));
            groupList1.Add(new Group(2, "Phizics"));

            var Group1Students1 =
            from s in studentList
            join
             g in groupList1 on s.GroupNumber equals g.GroupNumber
            group s by g.DepartmentName into gg
            select new { gg.Key, values = gg };

            //foreach (var st in Group1Students1)
            //{
            //    Console.WriteLine(st.Key);
            //    foreach (var item in st.values)
            //    {
            //        Console.WriteLine(item.Firstname);
            //    }
            //    Console.WriteLine();
            //}


            //Rewrite the previous using extension methods.
            var Group1StudentsExtension = studentList.Join(groupList1,
            (o => o.GroupNumber), (p => p.GroupNumber),
            (o, p) => new { deptName = p.DepartmentName, stud = o }).GroupBy(g => g.deptName).Select(s=>new {s.Key,values=s });

            foreach (var st in Group1StudentsExtension)
            {
                Console.WriteLine(st.Key);
                foreach (var item in st.values)
                {
                    Console.WriteLine(item.stud.Firstname);
                }
                Console.WriteLine();
            }
        }
    }
}
